package lia.org.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import lia.org.model.Car;
import lia.org.model.Filter;
import lia.org.model.JsonCar;
import lia.org.model.Marca;
import lia.org.model.Modelo;
import lia.org.service.CarService;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.googlecode.objectify.Query;

@Controller
@RequestMapping(value = "/car")
public class CarController extends CommonControl<Car> {

	private CarService carService;

	public CarService getCarService() {
		return carService;
	}

	@Autowired
	public void setCarService(CarService carService) {
		this.carService = carService;
	}

	@RequestMapping(method = RequestMethod.GET, value = "/get/{vin}", produces = "application/json")
	public @ResponseBody
	Car get(@PathVariable("vin") String vin) {
		return getCarService().getById(vin);
	}

	@RequestMapping(method = RequestMethod.GET, value = "/delete/{vin}", produces = "application/json")
	public @ResponseBody
	Map<String, ? extends Object> deleteById(@PathVariable("vin") String vin) {
		try {
			getCarService().deleteById(getCarService().getById(vin));
			return getModelMapSucces("OK");
		} catch (Exception e) {
			return getModelMapError(e.getMessage());
		}

	}

	@RequestMapping(method = RequestMethod.GET, value = "/listPag", produces = "application/json")
	public @ResponseBody
	Map<String, ? extends Object> carListPag(
			@RequestParam(value = "start", required = false) int start,
			@RequestParam(value = "limit", required = false) int limit,
			@RequestParam(value = "filter", required = false) String filter) {

		List<Filter> filtros = new ArrayList<Filter>();
		JsonParser jp;
		try {
			if (filter!=null)
			{				
				jp = new JsonFactory().createJsonParser(filter);
				ObjectMapper mapper = new ObjectMapper();
				jp.nextToken(); // START_ARRAY
				while (jp.nextToken() != JsonToken.END_ARRAY) {
					filtros.add((Filter) mapper.readValue(jp, 
							new TypeReference<Filter>() {}));
				}
			}
		} catch (JsonParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Query<Car> q = getCarService().getCarDao().ofy().
				query(Car.class);
		
		for (Filter filtro : filtros) {
			
			if (filtro.getProperty().equals("precioMax"))
				q.filter("precio <", new Integer(filtro.getValue()));
			else if (filtro.getProperty().equals("precioMin"))
				q.filter("precio >", new Integer(filtro.getValue()));
			else if (!filtro.getValue().equals("Todos"))
				q.filter(filtro.getProperty(), filtro.getValue());
				
		}		
		int cant = q.list().size();
		
		q.limit(limit).offset(start).
		order("precio").
		order("modelo.marca.name").
		order("modelo.name").
		order("color");	
		
	
		return getMap(q.list(),cant);
	}

	@RequestMapping(method = RequestMethod.GET, value = "/list", produces = "application/json")
	public @ResponseBody
	Map<String, ? extends Object> carList() {
		for (Car car : getCarService().findAll(null)) {
			car.setModelo(carService.getModeloDao().getByProperty("name", "palio"));
			car.setPrecio(20000);
			carService.getCarDao().add(car);
			
		}
		return getMap(getCarService().findAll(null), getCarService().findAll(null).size());
	}

	// http://localhost:8888/car/create?vin=1&color=222
	@RequestMapping(method = RequestMethod.POST, value = "/create", produces = "application/json")
	public @ResponseBody
	Map<String, ? extends Object> create(
			@RequestParam(value = "vin", required = true) String vin,
			@RequestParam(value = "color", required = false) String color) {
		try {
			getCarService().add(new Car(vin, color));
			return getModelMapSucces("OK");
		} catch (Exception e) {
			return getModelMapError(e.getMessage());
		}

	}
	
	@RequestMapping(method = RequestMethod.GET, value = "/carga", produces = "application/json")
	public @ResponseBody
	Map<String, ? extends Object> carga() {

	
		
		/*carService.getMarcaDao().add(new Marca("Fiat"));
		carService.getMarcaDao().add(new Marca("Renault"));
		carService.getMarcaDao().add(new Marca("Peugeot"));
		carService.getMarcaDao().add(new Marca("Chevrolet"));	
		
		carService.getModeloDao().add(new Modelo("Clio", carService.getMarcaDao().getByProperty("name", "Renault")));	
		carService.getModeloDao().add(new Modelo("Speedway", carService.getMarcaDao().getByProperty("name", "Renault")));
		carService.getModeloDao().add(new Modelo("Logan", carService.getMarcaDao().getByProperty("name", "Renault")));	
		carService.getModeloDao().add(new Modelo("12", carService.getMarcaDao().getByProperty("name", "Renault")));
		carService.getModeloDao().add(new Modelo("18", carService.getMarcaDao().getByProperty("name", "Renault")));
		
		carService.getModeloDao().add(new Modelo("148", carService.getMarcaDao().getByProperty("name", "Fiat")));	
		carService.getModeloDao().add(new Modelo("Palio", carService.getMarcaDao().getByProperty("name", "Fiat")));
		carService.getModeloDao().add(new Modelo("Uno", carService.getMarcaDao().getByProperty("name", "Fiat")));	
		carService.getModeloDao().add(new Modelo("Punto", carService.getMarcaDao().getByProperty("name", "Fiat")));
		carService.getModeloDao().add(new Modelo("Spazio", carService.getMarcaDao().getByProperty("name", "Fiat")));
		
		carService.getModeloDao().add(new Modelo("106", carService.getMarcaDao().getByProperty("name", "Peugeot")));	
		carService.getModeloDao().add(new Modelo("206", carService.getMarcaDao().getByProperty("name", "Peugeot")));
		carService.getModeloDao().add(new Modelo("307", carService.getMarcaDao().getByProperty("name", "Peugeot")));	
		
		
		carService.getModeloDao().add(new Modelo("Clasic", carService.getMarcaDao().getByProperty("name", "Chevrolet")));	
		carService.getModeloDao().add(new Modelo("Aveo", carService.getMarcaDao().getByProperty("name", "Chevrolet")));
		carService.getModeloDao().add(new Modelo("Corsa", carService.getMarcaDao().getByProperty("name", "Chevrolet")));	
		carService.getModeloDao().add(new Modelo("Cruze", carService.getMarcaDao().getByProperty("name", "Chevrolet")));*/
		
		carService.add(new Car("cruze001", new Modelo("Cruze", carService.getMarcaDao().getByProperty("name", "Chevrolet")), "azul", 50000,"san martin 456, Viedma"));
		carService.add(new Car("Aveo001", new Modelo("Aveo", carService.getMarcaDao().getByProperty("name", "Chevrolet")), "negro", 60000,"colon 300, Viedma"));
		carService.add(new Car("Clasic001", new Modelo("Clasic", carService.getMarcaDao().getByProperty("name", "Chevrolet")), "gris", 40000,"25 de mayo 220, Viedma"));
		carService.add(new Car(new Date().toString(), new Modelo("Corsa", carService.getMarcaDao().getByProperty("name", "Chevrolet")), "negro", 36000,"dorrego 320, Viedma"));
		carService.add(new Car(new Date().toString(), new Modelo("Corsa", carService.getMarcaDao().getByProperty("name", "Chevrolet")), "blanco", 35000,"alvear 250, Viedma"));
		
		
		carService.add(new Car("106001", new Modelo("106", carService.getMarcaDao().getByProperty("name", "Peugeot")), "gris", 60000,"moreno 200, Viedma"));
		carService.add(new Car("206001", new Modelo("206", carService.getMarcaDao().getByProperty("name", "Peugeot")), "blanco", 35000,"moreno 400, Viedma"));
		carService.add(new Car(new Date().toString(), new Modelo("307", carService.getMarcaDao().getByProperty("name", "Peugeot")), "negro", 96000,"san martin 456, Viedma"));
		carService.add(new Car(new Date().toString(), new Modelo("307", carService.getMarcaDao().getByProperty("name", "Peugeot")), "azul", 96000,"san martin 456, Viedma"));
		
		carService.add(new Car("148001", new Modelo("148", carService.getMarcaDao().getByProperty("name", "Fiat")), "blanco", 35000,"av villarino 300, Viedma"));
		carService.add(new Car("Punto001", new Modelo("Punto", carService.getMarcaDao().getByProperty("name", "Fiat")), "negro", 75000,"brown 456, Viedma"));
		carService.add(new Car(new Date().toString(), new Modelo("Uno", carService.getMarcaDao().getByProperty("name", "Fiat")), "gris", 25000,"brown 130, Viedma"));
		carService.add(new Car(new Date().toString(), new Modelo("Spazio", carService.getMarcaDao().getByProperty("name", "Fiat")), "negro", 15000,"islas malvinas 120, Viedma"));
		
		carService.add(new Car("Logan001", new Modelo("Logan", carService.getMarcaDao().getByProperty("name", "Renault")), "azul", 90000,"san martin 1000, Viedma"));
		carService.add(new Car("18001", new Modelo("18", carService.getMarcaDao().getByProperty("name", "Renault")), "gris", 15000,"caseros 100, Viedma"));
		carService.add(new Car("12001", new Modelo("12", carService.getMarcaDao().getByProperty("name", "Renault")), "amarillo", 10000,"caseros 300, Viedma"));
		carService.add(new Car("12002", new Modelo("12", carService.getMarcaDao().getByProperty("name", "Renault")), "azul", 10000,"zatti 456, Viedma"));
		carService.add(new Car("Speedway001", new Modelo("Speedway", carService.getMarcaDao().getByProperty("name", "Renault")), "azul", 80000,"zatti 100, Viedma"));
		carService.add(new Car("Clio001", new Modelo("Clio", carService.getMarcaDao().getByProperty("name", "Renault")), "blanco", 30000,"hieldeman 96, Viedma"));
		
	
		return getMap(carService.findAll(""));
	}

}
